//package com.io.jar;
//
//import com.common.utils.CommonException;
//
//import javax.security.auth.login.Configuration;
//import java.io.File;
//import java.io.IOException;
//import java.net.URISyntaxException;
//import java.net.URL;
//import java.util.Collections;
//import java.util.List;
//import java.util.jar.Attributes;
//import java.util.jar.JarFile;
//import java.util.jar.Manifest;
//
///**
// * @author xin.ding
// * @date 2021/5/19 20:40
// */
//public class PackagedProgram {
//
//    /**
//     * Property name of the entry in JAR manifest file that describes the Flink specific entry point.
//     */
//    public static final String MANIFEST_ATTRIBUTE_ASSEMBLER_CLASS = "program-class";
//
//    /**
//     * Property name of the entry in JAR manifest file that describes the class with the main method.
//     */
//    public static final String MANIFEST_ATTRIBUTE_MAIN_CLASS = "Main-Class";
//
//    private final URL jarFile;
//
//    private final String[] args;
//
//
//    private final Class<?> mainClass;
//
//    private final List<File> extractedTempLibraries;
//
//    private final List<URL> classpaths;
//
//    private ClassLoader userCodeClassLoader;
//
//
//    public PackagedProgram(File jarFile,
//                           List<URL> classpaths,
//                           Configuration configuration,
//                           String... args) {
//
//        URL jarFileUrl = null;
//        if (jarFile != null) {
//            try {
//                jarFileUrl = jarFile.getAbsoluteFile().toURI().toURL();
//                checkJarFile(jarFileUrl);
//            } catch (Exception e1) {
//                throw new IllegalArgumentException("The jar file is invalid.");
//            }
//
//
//        }
//
//        this.jarFile = jarFileUrl;
//        this.args = args == null ? new String[0] : args;
//
//
//        String entryPointClassName = getEntryPointClassNameFromJar(jarFileUrl);
//
//
//        // now that we have an entry point, we can extract the nested jar files (if any)
//        this.extractedTempLibraries = jarFileUrl == null ? Collections.emptyList() : extractContainedLibraries(jarFileUrl);
//        this.classpaths = classpaths;
//        this.userCodeClassLoader =
//                JobWithJars.buildUserCodeClassLoader(getAllLibraries(), classpaths, getClass().getClassLoader(), configuration);
//
//        // load the entry point class
//        this.mainClass = loadMainClass(entryPointClassName, userCodeClassLoader);
//
//        // if the entry point is a program, instantiate the class and get the plan
//        if (Program.class.isAssignableFrom(this.mainClass)) {
//            Program prg = null;
//            try {
//                prg = InstantiationUtil.instantiate(this.mainClass.asSubclass(Program.class), Program.class);
//            } catch (Exception e) {
//                // validate that the class has a main method at least.
//                // the main method possibly instantiates the program properly
//                if (!hasMainMethod(mainClass)) {
//                    throw new ProgramInvocationException("The given program class implements the " +
//                            Program.class.getName() + " interface, but cannot be instantiated. " +
//                            "It also declares no main(String[]) method as alternative entry point", e);
//                }
//            } catch (Throwable t) {
//                throw new ProgramInvocationException("Error while trying to instantiate program class.", t);
//            }
//            this.program = prg;
//        } else if (hasMainMethod(mainClass)) {
//            this.program = null;
//        } else {
//            throw new ProgramInvocationException("The given program class neither has a main(String[]) method, nor does it implement the " +
//                    Program.class.getName() + " interface.");
//        }
//    }
//
//
//    public static void checkJarFile(URL jar) throws IOException {
//        File jarFile;
//        try {
//            jarFile = new File(jar.toURI());
//        } catch (URISyntaxException e) {
//            throw new IOException("JAR file path is invalid '" + jar + '\'');
//        }
//        if (!jarFile.exists()) {
//            throw new IOException("JAR file does not exist '" + jarFile.getAbsolutePath() + '\'');
//        }
//        if (!jarFile.canRead()) {
//            throw new IOException("JAR file can't be read '" + jarFile.getAbsolutePath() + '\'');
//        }
//
//        try (JarFile ignored = new JarFile(jarFile)) {
//            // verify that we can open the Jar file
//        } catch (IOException e) {
//            throw new IOException("Error while opening jar file '" + jarFile.getAbsolutePath() + '\'', e);
//        }
//    }
//
//
//    private static String getEntryPointClassNameFromJar(URL jarFile) {
//        JarFile jar;
//        Manifest manifest;
//        String className;
//
//        // Open jar file
//        try {
//            jar = new JarFile(new File(jarFile.toURI()));
//        } catch (URISyntaxException use) {
//            throw new CommonException("Invalid file path '" + jarFile.getPath() + "'", use);
//        } catch (IOException ioex) {
//            throw new CommonException("Error while opening jar file '" + jarFile.getPath() + "'. "
//                    + ioex.getMessage(), ioex);
//        }
//
//        // jar file must be closed at the end
//        try {
//            // Read from jar manifest
//            try {
//                manifest = jar.getManifest();
//            } catch (IOException ioex) {
//                throw new CommonException("The Manifest in the jar file could not be accessed '"
//                        + jarFile.getPath() + "'. " + ioex.getMessage(), ioex);
//            }
//
//            if (manifest == null) {
//                throw new CommonException("No manifest found in jar file '" + jarFile.getPath() + "'. The manifest is need to point to the program's main class.");
//            }
//
//            Attributes attributes = manifest.getMainAttributes();
//
//            // check for a "program-class" entry first
//            className = attributes.getValue(MANIFEST_ATTRIBUTE_ASSEMBLER_CLASS);
//            if (className != null) {
//                return className;
//            }
//
//            // check for a main class
//            className = attributes.getValue(MANIFEST_ATTRIBUTE_MAIN_CLASS);
//            if (className != null) {
//                return className;
//            } else {
//                throw new CommonException("Neither a '" + MANIFEST_ATTRIBUTE_MAIN_CLASS + "', nor a '" +
//                        MANIFEST_ATTRIBUTE_ASSEMBLER_CLASS + "' entry was found in the jar file.");
//            }
//        } finally {
//            try {
//                jar.close();
//            } catch (Exception t) {
//                throw new CommonException("Could not close the JAR file: " + t.getMessage(), t);
//            }
//        }
//    }
//}
